package cn.jiyun.mailutils;

import lombok.extern.slf4j.Slf4j;

import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeUtility;
import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.util.Properties;

@Slf4j
public class SenderUtil {

    /**
     * 发送者服务器配置
     */
    private static final SenderProperties senderProperties;
    static {
        senderProperties = new SenderProperties();
        senderProperties.setMailSmtpAuth(true);
        senderProperties.setUserName("1170596762@qq.com");
        // 这里企业邮箱中，使用登录密码，其他私人邮箱使用客户端授权码
        senderProperties.setPassword("helidyopdkrgbaab");
        senderProperties.setMailHost("smtp.qq.com");
        senderProperties.setMailTransportProtocol("smtp");
    }

    /**
     * 对外提供的发送邮件方法
     * @param senderMessage
     * @return
     */
    public static boolean send(SenderMessage senderMessage){
        try {
            doSend(senderProperties,senderMessage);
            return true;
        } catch (Exception e) {
            log.error("发送邮件失败",e);
            return false;
        }
    }


    /**
     * 发送邮件
     * @param senderProperties
     */
    private static void doSend(SenderProperties senderProperties, SenderMessage senderMessage) throws MessagingException, UnsupportedEncodingException {

        Properties properties = getProperties(senderProperties);
        Authenticator authenticator = getAuthenticator(senderProperties);
        // 根据properties和authenticator 创建session
        Session session = Session.getDefaultInstance(properties, authenticator);
        Message message = createMessage(session,senderMessage,senderProperties);
        // 发送
        Transport.send(message);
        log.info("email send successed!");
    }

    /**
     * 获取授权信息
     * @param senderProperties
     * @return
     */
    private static Authenticator getAuthenticator(SenderProperties senderProperties){
        // 认证信息，即发件人用户名和密码，这里的密码是授权码，不是登录密码，授权码在邮箱设置获取
        return new Authenticator() {
            @Override
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(senderProperties.getUserName(), senderProperties.getPassword());
            }
        };
    }

    /**
     * 获取连接信息
     * @param senderProperties
     * @return
     */
    private static Properties getProperties(SenderProperties senderProperties){
        // smtp服务器设置
        Properties props = new Properties();
        // 默认的邮件传输协议
        props.setProperty("mail.transport.protocol", senderProperties.getMailTransportProtocol());
        // 设置邮件服务器主机名
        props.put("mail.host", senderProperties.getMailHost());
        //SMTP 服务器的端口(非SSL连接的端口一般默认为 25, 可以不添加, 如果开启了 SSL 连接,需要改为对应邮箱的 SMTP 服务器的端口, 具体可查看对应邮箱服务的帮助,QQ邮箱的SMTP(SLL)端口为465或587, 其他邮箱自行去查看)
        if (senderProperties.getMailPort() != null){
            props.put("mail.port", senderProperties.getMailPort());
        }
        // 设置是否安全验证,默认为false,一般情况都设置为true
        props.put("mail.smtp.auth", senderProperties.isMailSmtpAuth());
        return props;
    }

    /**
     * 创建邮件消息
     * @param session
     * @param senderMessage
     * @param senderProperties
     * @return
     * @throws UnsupportedEncodingException
     * @throws MessagingException
     */
    private static Message createMessage(Session session, SenderMessage senderMessage, SenderProperties senderProperties) throws UnsupportedEncodingException, MessagingException {
        // 根据session创建一个Message，即邮件消息
        Message message = new MimeMessage(session);
        // 设置邮件消息的发送者
        InternetAddress sender = new InternetAddress(senderMessage.getFrom(), senderMessage.getPersonal(), "utf-8");
        message.setFrom(sender);
        // 设置邮件的接受者，如果有多个接受者，调用  message.setRecipients
        InternetAddress receiver = new InternetAddress(senderMessage.getTo());
        message.setRecipient(Message.RecipientType.TO, receiver);
        // 设置主题
        message.setSubject(MimeUtility.encodeText(senderMessage.getSubject()));
        // 发送时间
        message.setSentDate(new Date());
        // 邮件正文（可以使用html标签）
        message.setContent(senderMessage.getContent(), "text/html;charset=utf-8");
        // 保存更改
        message.saveChanges();
        return message;
    }
}
